package top.truehaku.generator.code.application.assembler;

import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import top.truehaku.generator.code.application.vo.*;
import top.truehaku.generator.code.domain.model.code.Code;
import top.truehaku.generator.code.domain.model.column.Column;
import top.truehaku.generator.code.domain.model.table.Table;
import top.truehaku.generator.code.domain.model.table.TableComment;
import top.truehaku.generator.code.domain.model.table.TableId;
import java.util.List;

@Mapper
public interface VariableMapper {
    VariableMapper instance = Mappers.getMapper(VariableMapper.class);

    @Mapping(target = "name",expression = "java(table.getTableId().getTableName())")
    @Mapping(target = "scheme",expression = "java(table.getTableId().getTableScheme())")
    @Mapping(target = "alias",expression = "java(table.getTableAlias())")
    @Mapping(target = "comment",expression = "java(table.getTableComment().getTableComment())")
    @Mapping(target = "module",expression = "java(table.getModuleName())")
    @Mapping(target = "lastname",expression = "java(table.getLastname())")
    @Mapping(target = "containsUnique",expression = "java(table.containsUnique())")
    @Mapping(target = "containsCombineColumn",expression = "java(table.containsCombineColumn())")
    TableInfo tableInfo(Table table);

    @Named(value = "columnInfo")
    @Mapping(target = "name",expression = "java(column.getColumnId().getColumnName())")
    @Mapping(target = "type",expression = "java(column.getColumnType().getSimpleType())")
    @Mapping(target = "comment",expression = "java(column.getColumnComment().getComment())")
    @Mapping(target = "nullable",expression = "java(column.getNullable())")
    @Mapping(target = "primaryKey",expression = "java(column.getPrimaryKey())")
    @Mapping(target = "autoIncrement",expression = "java(column.getAutoIncrement())")
    @Mapping(target = "ordinalPosition",expression = "java(column.getOrdinalPosition())")
    @Mapping(target = "uniqueKey",expression = "java(column.getUniqueKey())")
    @Mapping(target = "remark",expression = "java(column.getColumnComment().getRemark())")
    @Mapping(target = "isCombine",expression = "java(column.getColumnComment().isCombine())")
    ColumnInfo columnInfo(Column column);

    @Named(value = "fieldInfo")
    @Mapping(target = "type",expression = "java(column.getColumnType().getJavaType().getSimpleName())")
    @Mapping(target = "name",expression = "java(column.getFieldName())")
    @Mapping(target = "capitalizeName",expression = "java(column.getFieldCapitalizeName())")
    @Mapping(target = "parentIncluded",expression = "java(column.getParentIncluded())")
    @Mapping(target = "isCondition",expression = "java(column.isCondition())")
    @Mapping(target = "condition",expression = "java(column.getCondition())")
    @Mapping(target = "isCombine",expression = "java(column.getColumnComment().isCombine())")
    @Mapping(target = "column",expression = "java(columnInfo(column))")
    @Mapping(target = "combineFields",expression = "java(fields(column.getCombineColumns()))")
    FieldInfo fieldInfo(Column column);

    @IterableMapping(qualifiedByName = "columnInfo")
    List<ColumnInfo> columns(List<Column> columns);
    @IterableMapping(qualifiedByName = "fieldInfo")
    List<FieldInfo> fields(List<Column> columns);

    @Mapping(target = "entityName",expression = "java(table.getEntityName())")
    @Mapping(target = "objectName",expression = "java(table.getObjectName())")
    @Mapping(target = "table",expression = "java(tableInfo(table))")
    @Mapping(target = "fields",expression = "java(fields(table.getColumnList()))")
    @Mapping(target = "containsDate",expression = "java(table.containsDate())")
    @Mapping(target = "containsString",expression = "java(table.containsString())")
    @Mapping(target = "primaryField",expression = "java(fieldInfo(table.getPrimaryColumn()))")
    EntityInfo entityInfo(Table table);

    @Mapping(target = "name",expression = "java(code.getFile().getSimpleName())")
    @Mapping(target = "packageName",expression = "java(code.getDirectory().getPackage())")
    @Mapping(target = "typeName",expression = "java(code.getTypeName())")
    @Mapping(target = "parent",expression = "java(clazzInfo(code.getParent()))")
    ClazzInfo clazzInfo(Code code);

    @Mapping(target = "clazz",expression = "java(clazzInfo(code))")
    @Mapping(target = "entity",expression = "java(entityInfo(table))")
    @Mapping(target = "createTime",expression = "java(new java.util.Date())")
    Variable variable(Code code,Table table);

    public static void main(String[] args) {
        Table table = new Table(new TableId("core","monitor_operation_log"),new TableComment("这是注释"),null);
        TableInfo tableInfo = VariableMapper.instance.tableInfo(table);
        System.out.println(tableInfo);
    }

}
